//
//  flags.m
//  Tetravex
//
//  Created by Holmes Futrell on 7/13/08.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//

#import "GLSprite.h"
#import "GLTexture.h"

//#import "common.h"

#import <CoreGraphics/CoreGraphics.h>

@interface GLSprite (internalMethods) 
-(void)generateCoordinates;
@end

@implementation GLSprite

- (unsigned int)enableDefaultFlags:(unsigned int)flags {
	if ((flags&kGLSpriteCenterModeFlags) == 0) {
		flags |= kGLSpriteCenterModeTopLeft;
	}
	return flags;
}

-(void)generateCoordinates:(int)flags {
	
	flags = [self enableDefaultFlags: flags];
	
	if (vertices) free(vertices);
	if (texCoords) free(texCoords);
	
	vertices	= (GLfloat *)malloc( 8 * sizeof(GLfloat) );
	texCoords	= (GLfloat *)malloc( 8 * sizeof(GLfloat) );
	
	GLfloat width = (float)texture.width;
	GLfloat height = (float)texture.height;
	GLfloat maxx = (float)width / texture.internalWidth;
	GLfloat maxy = (float)height / texture.internalHeight;
	
	texCoords[0] = 0.0f; texCoords[1] = 0.0f;
	texCoords[2] = maxx; texCoords[3] = 0.0f;
	texCoords[4] = 0.0f; texCoords[5] = maxy;
	texCoords[6] = maxx; texCoords[7] = maxy;
		
	if (flags & kGLSpriteCenterModeTopLeft) {
		vertices[0] = 0.0f; vertices[1] = 0.0f;
		vertices[2] = width; vertices[3] = 0.0f;
		vertices[4] = 0.0f; vertices[5] = height;
		vertices[6] = width; vertices[7] = height;
	}
	else if (flags & kGLSpriteCenterModeCenter) {
		vertices[0] = -width / 2.0f; vertices[1] = -height / 2.0f;
		vertices[2] = width / 2.0f;  vertices[3] = -height / 2.0f;
		vertices[4] = -width / 2.0f; vertices[5] = height / 2.0f;
		vertices[6] = width / 2.0f; vertices[7] = height / 2.0f;
	}
	else {
		/* you could put a mode for custom center-point here */
		NSLog(@"Bad center mode specified!");
	}
	
}


-(id)init {
	self = [super init];
	vertices = texCoords = nil;
	return self;
}

-(id)initWithSize:(CGSize)size flags:(int)flags {
	
	self = [self init];
	texture = [[GLTexture alloc] initWithSize: size flags: flags];
	[self generateCoordinates: flags];
	
	return self;
	
}

+(id)spriteWithContentsOfFile:(NSString *)path {
	return [[[GLSprite alloc] initWithContentsOfFile: path] autorelease];
}

+(id)spriteWithContentsOfFile:(NSString *)path  flags:(int)flags {
	return [[[GLSprite alloc] initWithContentsOfFile: path flags: flags] autorelease];
}

-(id)initWithContentsOfFile:(NSString *)path {
	return (self = [self initWithContentsOfFile: path flags: 0]);
}

-(id)initWithContentsOfFile:(NSString *)path flags:(int)flags {
	
	self = [self init];
	texture = [[GLTexture alloc] initWithFile: path flags: flags];
	[self generateCoordinates: flags];
	return self;
	
}

-(id)initWithPVRTC:(NSString *)file size:(unsigned int)size bpp:(unsigned int)bpp flags:(unsigned int)flags {
	self = [self init];
	texture = [[GLTexture alloc] initWithPVRTC: file size: size bpp: bpp flags: flags];
	[self generateCoordinates: flags];
	return self;	
}

-(void)draw {
	
	glBindTexture(GL_TEXTURE_2D, texture.descriptor);		
	// Sets up pointers and enables states needed for using vertex arrays and textures
    glVertexPointer(2, GL_FLOAT, 0, vertices);
    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
	
}

/* draw any subset of the texture to any rectangular region */
void drawRect(CGRect src, CGRect dst, GLSprite *sprite) {
		
	GLfloat vertices[8];
	GLfloat texcoords[8];
	
	float iwidth = sprite.internalWidth;
	float iheight = sprite.internalHeight;
	
	texcoords[0] = src.origin.x;					 texcoords[1] = src.origin.y;
	texcoords[2] = src.origin.x + src.size.width;    texcoords[3] = src.origin.y;
	texcoords[4] = src.origin.x;					 texcoords[5] = src.origin.y + src.size.height;
	texcoords[6] = src.origin.x + src.size.width;    texcoords[7] = src.origin.y + src.size.height;
	
	/* scale the texture coordinates */
	int i;
	for (i=0; i<4; i++) {
		texcoords[2*i+0] /= iwidth;
		texcoords[2*i+1] /= iheight;
	}
	
	vertices[0] = dst.origin.x;					 vertices[1] = dst.origin.y;
	vertices[2] = dst.origin.x + dst.size.width; vertices[3] = dst.origin.y;
	vertices[4] = dst.origin.x;					 vertices[5] = dst.origin.y + dst.size.height;
	vertices[6] = dst.origin.x + dst.size.width; vertices[7] = dst.origin.y + dst.size.height;
	
	glVertexPointer(2, GL_FLOAT, 0, vertices);
	glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
	
}


-(void)dealloc {
	
	if (vertices)
		free(vertices);
	
	if (texCoords)
		free(texCoords);
	
	[texture release];
	[super dealloc];
}

-(GLuint)width { return texture.width;}
-(GLuint)height { return texture.height;}
-(GLuint)internalWidth { return texture.internalWidth;}
-(GLuint)internalHeight { return texture.internalHeight;}
-(GLuint)descriptor { return texture.descriptor;}

@end
